/**
 * 
 */
package pruebas.tiendaOl.general;

import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;

import com.intelap.utils.ProductorRecursos;

/** @author ggpollit */
public class FabricaManejadorExcepcionesJsf extends ExceptionHandlerFactory {

	private final ExceptionHandlerFactory parent;

	public FabricaManejadorExcepcionesJsf(ExceptionHandlerFactory parent) {
		this.parent = parent;
	}

	@Override
	public ExceptionHandler getExceptionHandler() {
		return new ManejadorExcepcionesJsf(parent.getExceptionHandler());
	}

	static class ManejadorExcepcionesJsf extends ExceptionHandlerWrapper {
		private static Logger log = ProductorRecursos.getLogger(ManejadorExcepcionesJsf.class);
		private final ExceptionHandler wrapped;

		public ManejadorExcepcionesJsf(ExceptionHandler wrapped) {
			this.wrapped = wrapped;
		}

		@Override
		public ExceptionHandler getWrapped() {
			return wrapped;
		}

		@Override
		public void handle() throws FacesException {
			boolean yaSeHaAtajadoAlgunaExcepcionCuyoTratamientoEsMostrarPaginaErrorInactividad = false;
			//Iterate over all unhandeled exceptions
			Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
			while (i.hasNext()) {
				ExceptionQueuedEvent event = i.next();
				ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
				Throwable t = context.getException();
				
				if (t instanceof ViewExpiredException || t.getClass().getSimpleName().equals("NonexistentConversationException")) {
					log.log(Level.INFO, "El tiempo de inactividad tolerado ha expirado: ", t);
					try {
						if (!yaSeHaAtajadoAlgunaExcepcionCuyoTratamientoEsMostrarPaginaErrorInactividad) {
						final FacesContext fc = FacesContext.getCurrentInstance();
						fc.addMessage(
								null,
								new FacesMessage(
										"Disculpe por favor. El tiempo de inactividad ha expirado. Por razones de seguridad debe volver a loguearse."));
						fc.renderResponse();
						fc.getExternalContext().invalidateSession();

						NavigationHandler nav = fc.getApplication().getNavigationHandler();
						nav.handleNavigation(fc, null, "/paginas/error");
							yaSeHaAtajadoAlgunaExcepcionCuyoTratamientoEsMostrarPaginaErrorInactividad = true;
						}
					} finally {
						i.remove();
					}
				} else {
					log.log(Level.SEVERE, "Error severo en JSF Lifcycle:", t);
				}

			}
			//let the parent handle the rest
			getWrapped().handle();
		}
	}
}
